﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace C4F.DevKit.Calendar.Parser
{
    /// <summary>
    /// A class containing methods to help with parsing iCal files.
    /// </summary>
    public class ParserHelper
    {
        /// <summary>
        /// Removes the iCal escape characters from a string, as defined by RFC 2445.
        /// </summary>
        /// <param name="input">The string from which to remove escape characters.</param>
        /// <returns>The input string with escape characters removed.</returns>
        public static string RemoveEscapeChars(string input)
        {
            string output = "";
            bool isEscapeCharacter = false;

            foreach (char character in input)
            {
                if (character == '\\' && (!isEscapeCharacter))
                {
                    isEscapeCharacter = true;
                }
                else if (isEscapeCharacter && character.ToString().ToUpper().Equals("N"))
                {
                    output = output + '\n';
                    isEscapeCharacter = false;
                }
                else
                {
                    output = output + character;
                    isEscapeCharacter = false;
                }
            }

            return output;
        }

        /// <summary>
        /// Inserts escape characters in the appropriate places in the string as specified
        /// by RFC 2445.
        /// </summary>
        /// <param name="input">The string into which to insert escape characters.</param>
        /// <returns>The input string with escape characters inserted.</returns>
        public static string InsertEscapeChars(string input)
        {
            string result = "";

            foreach (char character in input)
            {
                if ("\\\n;,".IndexOf(character) == -1)
                {
                    result = result + character;
                }
                else if (character == '\n')
                {
                    result = result + "\\n";
                }
                else
                {
                    result = result + '\\' + character;
                }
            }

            return result;
        }

        /// <summary>
        /// Finds an attendee name on an ATTENDEE line in an iCal file.
        /// </summary>
        /// <param name="line">The ATTENDEE line to search.</param>
        /// <returns>The name of the attendee.</returns>
        public static string GetAttendeeName(string line)
        {
            return Regex.Match(line, "CN=([^;:,\x8\xA1F\x7F\"]+|\"[^\"]+\")").Groups[1].Value.Trim('"');
        }

        /// <summary>
        /// Gets an e-mail address from a line in an iCal file with a MAILTO property
        /// </summary>
        /// <param name="line">The input line to search.</param>
        /// <returns>The e-mail address.</returns>
        public static string GetEmailAddress(string line)
        {
            return Regex.Match(line, "MAILTO:(.*)$").Groups[1].Value;
        }

        /// <summary>
        /// Parses the parts out of a string representing a list of weekdays in a month.
        /// </summary>
        /// <param name="line">The string to parse.</param>
        /// <returns>The weeknumber and weekday abbreviation.</returns>
        public static string[] GetMonthWeekdayParts(string line)
        {
            GroupCollection matchGroups = Regex.Match(line, "((?:\\+|-)?\\d\\d?)?(SU|MO|TU|WE|TH|FR|SA)").Groups;
            string[] result = new string[2];
            result[0] = matchGroups[1].Value;
            result[1] = matchGroups[2].Value;
            return result;
        }

        /// <summary>
        /// Parses the parts of a string representing a duration.
        /// </summary>
        /// <param name="line">The string to parse.</param>
        /// <returns>The count and the increment abbreviation, both in string form.</returns>
        public static string[] GetDurationParts(string line)
        {
            GroupCollection groups = Regex.Match(line, "(\\d+)([WDHMS])").Groups;
            string[] results = new string[2];
            results[0] = groups[1].Value;
            results[1] = groups[2].Value;
            return results;
        }
    }
}
